package com.deyuanyun.pic.web.support.shiro;

import com.deyuanyun.pic.cache.SessionCacheSupport2;
import com.deyuanyun.pic.common.spring.SpringAppliction;
import com.deyuanyun.pic.common.util.ObjectUtil;
import com.deyuanyun.pic.controller.dto.UserSessionVO;
import com.deyuanyun.pic.domain.prvlg.CustomUser;
import com.deyuanyun.pic.domain.prvlg.Menu;
import com.deyuanyun.pic.service.prvlg.UserService;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

import java.util.*;

public class ShiroMonitorRealm extends AuthorizingRealm {
    static Logger logger=Logger.getLogger(ShiroMonitorRealm.class);

    /**
     * 这个是访问需要授权的页面的时候才会调用，如果使用了缓存，只会调用一次
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //todo admin帐户给予所有权限
        String currentUsername = (String)super.getAvailablePrincipal(principals);
        UserSessionVO sessionVO= SessionCacheSupport2.get(currentUsername);

        String[] rs = StringUtils.split(sessionVO.getRoleCodes());
        SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
        Set<String> strings=new HashSet<>(Arrays.asList(rs));
        if ("admin".equals(currentUsername)){
            strings.add("admin");
        }
        simpleAuthorInfo.setRoles(strings);
        List<Menu> menuList=sessionVO.getMenuList();

        Set<String> strings1=new HashSet<String>();
        strings1.add("pipeuser");
        if ("admin".equals(currentUsername)){
            strings1.add("admin:manage");
        }
        if (ObjectUtil.isNotNullEmpty(menuList)){
            for (Menu menu:menuList){
                strings1.add(menu.getCode());
            }
        }
        simpleAuthorInfo.setStringPermissions(strings1);
        return simpleAuthorInfo;
        //return null;
    }

    /**
     * 登陆时调用
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
        String userId = token.getUsername();
        char[] pwd = token.getPassword();

        UserService userService = SpringAppliction.getBean(UserService.class);
        List<CustomUser> userList= null;
        try {
            userList = userService.getUser(userId);
        } catch (Exception e) {
            logger.error("",e);
        }
        if (ObjectUtil.isEmptyAll(userList)){
            throw new AuthenticationException("没有用户");
        }
        if (!"ACTIVATE".equals(userList.get(0).getState())){
            throw new DisabledAccountException("帐户已被禁用");
        }
        if (userList.size()>1){
            logger.error(">>>>>用户名"+userId+">>>数量大于了一个用户数据异常!");
            throw new AuthenticationException("用户数量不对");
        }
       //LockedAccountException.class
        AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(userId, userList.get(0).getPwd(), this.getName());
        this.setSession("currentUser", userId);

        // 3,600,000 milliseconds = 1 hour
        //SecurityUtils.getSubject().getSession().setTimeout(1800000);
        com.deyuanyun.pic.web.utils.SecurityUtils.setUser(userList.get(0));


            return authcInfo;

    }
/**
     * 将一些数据放到ShiroSession中,以便于其它地方使用
     * 比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到*/


    private void setSession(Object key, Object value){
        Subject currentUser = SecurityUtils.getSubject();
        if(null != currentUser){
            Session session = currentUser.getSession();
            if(null != session){
                session.setAttribute(key, value);
            }
        }
    }


    /**
     * 更新用户授权信息缓存.
     */
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }
    /**
     * 更新用户信息缓存.
     */
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    /**
     * 清除用户授权信息缓存.
     */
    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    /**
     * 清除用户信息缓存.
     */
    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    /**
     * 清空所有缓存
     */
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }


    /**
     * 清空所有认证缓存
     */
    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }

}
